﻿using DotNetCore.CAP;
using DotNetCore.CAP.Filter;
using Microsoft.Extensions.Caching.Distributed;

namespace TK.Common.CAP
{
    /// <summary>
    /// cap 消费端过滤器
    /// </summary>
    public class CapSubFilter : ISubscribeFilter
    {
        private readonly IDistributedCache _cache;

        /// <summary>
        /// ctor
        /// </summary>
        public CapSubFilter(IDistributedCache cache)
        {
            _cache = cache;
        }

        /// <summary>
        /// exception
        /// </summary>
        public Task OnSubscribeExceptionAsync(ExceptionContext context)
        {
            if (context.Exception is CapRepeatException)
            {
                context.ExceptionHandled = true;
            }

            return Task.CompletedTask;
        }

        /// <summary>
        /// after do
        /// </summary>
        public Task OnSubscribeExecutedAsync(ExecutedContext context)
        {
            var lockKey = $"cap.msg:{context.DeliverMessage.Headers["cap-msg-id"]}:{context.DeliverMessage.Headers["cap-msg-group"]}";
            _cache.SetString(lockKey, "1", new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = System.TimeSpan.FromHours(24) });
            return Task.CompletedTask;
        }

        /// <summary>
        /// before do
        /// </summary>
        public Task OnSubscribeExecutingAsync(ExecutingContext context)
        {
            var lockKey = $"cap.msg:{context.DeliverMessage.Headers["cap-msg-id"]}:{context.DeliverMessage.Headers["cap-msg-group"]}";
            if (_cache.GetString(lockKey) == "1")
            {
                throw new CapRepeatException("cap process is repeated");
            }

            return Task.CompletedTask;
        }
    }
}
